package com.casic.dao;

import com.casic.entity.IotData;
import com.casic.entity.vo.DeviceStateStatisticsVo;
import com.casic.entity.vo.DeviceStateVo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author xudezhi
 * @title: MongoDao
 * @projectName iot-platform
 * @description: MongoDao
 * @date 2021/4/1210:23:15
 */
@Repository
public interface MongoDao extends MongoRepository<IotData,String> {

    /**
     * 查询设备的数据
     * @param equipment
     * @param pageable
     * @return
     */
    @Query(value = "{'_id':{'$ne':null},equipment:?0}")
    List<IotData> findByEquipment(String equipment, Pageable pageable);

    /**
     * 按t查询最后一条
     * @param equipment 设备号
     * @param k 采集点
     * @return
     */
//    @Query(value = "{'_id':{'$ne':null},equipment:?0,k:?1}")
    IotData findFirstByEquipmentAndK(String equipment, String k,Sort sort);

    /**
     * 查询时间范围内的数据
     * @param equipment
     * @param k
     * @param startTime
     * @param endTime
     * @param sort
     * @return
     */
    List<IotData> findByEquipmentAndKAndTBetween(String equipment, String k,String startTime,String endTime,Sort sort);

    /**
     * 查询满足条件的第一条数据
     * @param equipment
     * @param k
     * @param startTime
     * @param endTime
     * @param sort
     * @return
     */
    IotData findFirstByEquipmentAndKAndTBetween(String equipment, String k, String startTime, String endTime, Sort sort);

    /**
     * 分页查询
     * @param equipment
     * @param k
     * @param startTime
     * @param endTime
     * @param pageable
     * @return
     */
    Page<IotData> findByEquipmentAndKAndTBetween(String equipment, String k, String startTime, String endTime, Pageable pageable);

    /**
     * 查询数量
     * @param orgId
     * @param state
     * @param v
     * @param startTime
     * @param endTime
     * @return
     */
//    @Aggregation(value={"{$match:{'orgId':{'$eq':?0},'k':{'$eq':?1},'v':{'$eq':?2},'t':{'$gt':?3,'$lt':?4}}}","{$group:{_id : '$equipment', num : { $sum: 1 }}}"})
//    List<DeviceStateStatisticsVo> findByOrgIdAndKAndVAndTBetween(String orgId, String state, String v, String startTime, String endTime);

    /**
     * 方法调优一次查询
     */
    @Aggregation(value={"{$match:{'orgId':{'$eq':?0},'k':{'$eq':?1},'t':{'$gt':?2,'$lt':?3}}}",
                        "{$sort:{'t':-1}}",
                        "{$group:{_id : '$equipment', v : { $addToSet: '$v'}}}",
                        "{$unwind:'$v'}",
                        "{$group:{_id:'$v',equipments:{$addToSet:'$_id'}}}",
                        "{$sort:{_id:-1}}"
    })
    List<DeviceStateStatisticsVo> findByOrgIdAndKAndTBetween(String orgId, String state,String startTime, String endTime);

    /**
     * 查询状态分组
     * @param state
     * @param startTime
     * @param endTime
     * @return
     */
    @Aggregation(value={"{$match:{'k':{'$eq':?0},'t':{'$gt':?1,'$lt':?2}}}",
            "{$sort:{'t':-1}}",
            "{$group:{_id : '$equipment', v : { $addToSet: '$v'}}}",
            "{$unwind:'$v'}",
            "{$group:{_id:'$v',equipments:{$addToSet:'$_id'}}}",
            "{$sort:{_id:-1}}"
    })
    List<DeviceStateStatisticsVo> findByKAndTBetween(String state, String startTime, String endTime);

    /**
     * 测试查询数量
     * @param orgId
     * @param state
     * @param v
     * @return
     */
    Integer countByOrgIdAndKAndV(String orgId, String state, String v);


    /**
     * 查询时间段内最新一条数据，作为设备的状态
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    @Aggregation(value={"{$match:{'k':{'$eq':'state'},'t':{'$gt':?0,'$lt':?1}}}",
            "{$sort:{'t':-1}}",
            "{$group:{_id : '$equipment', state : { $first: '$v'}}}",
            "{$sort:{_id:-1}}"
    })
    List<DeviceStateVo> findStateByTBetween(String startTime, String endTime);

}
